namespace AsyncLog
{
	using System;
	using System.Collections.Generic;
	using System.Globalization;
	using System.Threading;
	using System.Threading.Tasks;

	using ComponentFactory.Krypton.Toolkit;

	using PugLib;
	using PugLib.UI;

	internal sealed class AsyncLogController : TaskPresenter
	{
		private readonly List<AsyncLogTestDriver> _drivers;
		private readonly IEventAggregator _eventAggregator;
		private readonly List<LogEntry> _logEntries;
		
		internal AsyncLogController(TaskForm view)
			: base(view)
		{
			_eventAggregator = PugLib.EventAggregator.CreateDefault();
			_logEntries = new List<LogEntry>();
			_drivers = new List<AsyncLogTestDriver>();
		}

		internal IEventAggregator EventAggregator
		{
			get { return _eventAggregator; }
		}

		internal void Pause()
		{
			_drivers.ForEach(d => d.Stop());
		}

		public void AddMessage()
		{
			AddMessage(AsyncLogTestDriver.CreateRandomMessage());
		}

		public void AddMessage(String message)
		{
			Task.Factory.StartNew(AddMessageWorker, message);
		}

		private void AddMessageWorker(Object state)
		{
			String message = (state as String);
			String formatted = String.Format(CultureInfo.InstalledUICulture, "Thread {0}: {1}", Thread.CurrentThread.ManagedThreadId, message);

			LogEntry entry = new LogEntry(formatted, true);

			_logEntries.Add(entry);
			_eventAggregator.Publish(new NewMessage(entry));
		}

		internal void Clear(KryptonRichTextBox log)
		{
			lock (_logEntries)
			{
				_logEntries.Clear();
				log.Clear();
			}
		}

		internal void Start(AsyncLogDemo asyncLogDemo)
		{
			for (int i = 0; i < 11; i++)
			{
				_drivers.Add(new AsyncLogTestDriver(asyncLogDemo));
				_drivers[i].Start((i + 1) * 1000);
			}
		}
	}
}